#include "ServiceProxyAsyncService.h"
#include <boost/bind.hpp>



bool ServiceProxyAsyncService::addListen(){
    handleStudentListen();
    handleTeacherListen();
    return true;
}

grpc::Service* ServiceProxyAsyncService::getService(){
    return &m_service;
};

void ServiceProxyAsyncService::notify(void* tag){
    int seq = *((int*)(tag));
    auto iter = m_MapProxy.find(seq);
    if(m_MapProxy.end() == iter){
        return;
    }
    auto pBase = iter->second;
    m_MapProxy.erase(iter);

    pBase->funNext();
};

void ServiceProxyAsyncService::stop(){
    m_MapProxy.clear();
};

void ServiceProxyAsyncService::handleStudentListen(){
    auto pRequest = student_request_ptr(new student_request_ptr::element_type());
    auto pResponse = teacher_request_ptr(new teacher_request_ptr::element_type());
    auto pProxy = student_proxy_ptr(new student_proxy_ptr::element_type(&m_context));

    BaseProxyPtr pParam = BaseProxyPtr(new BaseProxyPtr::element_type());
    pParam->seq = ++m_seq;
    pParam->funNext = boost::bind(&ServiceProxyAsyncService::handleStudentWork, shared_from_this(), pRequest, pResponse, pProxy);
    m_service.RequestHelloStudent(&m_context, pRequest.get(), pProxy.get(), m_pQueue.get()
        , m_pQueue.get(), (void*)pParam->seq);
    m_MapProxy.insert(std::make_pair(pParam->seq, pParam));
};

void ServiceProxyAsyncService::handleStudentWork(student_request_ptr pRequest, teacher_request_ptr pResponse, student_proxy_ptr pProxy){
    handleStudentListen();

    

    BaseProxyPtr pParam(new BaseProxyPtr::element_type());
    pParam->seq = ++m_seq;
    pParam->funNext = boost::bind(
        &ServiceProxyAsyncService::deleteFromMap<student_request_ptr, teacher_request_ptr, student_proxy_ptr>, shared_from_this()
        , pRequest, pResponse, pProxy);
    pProxy->Finish(*pResponse,grpc::Status::OK, (void*)pParam->seq);
    m_MapProxy.insert(std::make_pair(pParam->seq, pParam));
};

void ServiceProxyAsyncService::handleTeacherListen(){
    auto pRequest = teacher_request_ptr(new teacher_request_ptr::element_type());
    auto pResponse = student_request_ptr(new student_request_ptr::element_type());
    auto pProxy = teacher_proxy_ptr(new teacher_proxy_ptr::element_type(&m_context));

    BaseProxyPtr pParam = BaseProxyPtr(new BaseProxyPtr::element_type());
    pParam->seq = ++m_seq;
    pParam->funNext = boost::bind(&ServiceProxyAsyncService::handleTeacherWork, shared_from_this(), pRequest, pResponse, pProxy);
    m_service.RequestHelloTeacher(&m_context, pRequest.get(), pProxy.get(), m_pQueue.get()
        , m_pQueue.get(), (void*)pParam->seq);
    m_MapProxy.insert(std::make_pair(pParam->seq, pParam));
};

void ServiceProxyAsyncService::handleTeacherWork(teacher_request_ptr pRequest, student_request_ptr pResponse, teacher_proxy_ptr pProxy){
    handleTeacherListen();

    

    BaseProxyPtr pParam(new BaseProxyPtr::element_type());
    pParam->seq = ++m_seq;
    pParam->funNext = boost::bind(
        &ServiceProxyAsyncService::deleteFromMap<teacher_request_ptr, student_request_ptr, teacher_proxy_ptr>, shared_from_this()
        , pRequest, pResponse, pProxy);
    pProxy->Finish(*pResponse,grpc::Status::OK, (void*)pParam->seq);
    m_MapProxy.insert(std::make_pair(pParam->seq, pParam));
};